package x.trident.core.util;

import cn.hutool.core.date.DateUtil;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateFormatUtils;
import x.trident.core.constants.DateFormatConstant;

import java.time.Duration;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;

/**
 * @Package:        com.frame.platform.utils
 * @FileName:       DateUtils.java
 * @ClassName:      DateUtils
 * @Description:    日期工具类
 * @Author:         wuqiangfu
 * @CreateDate:     2022/7/4 19:28
 * @UpdateUser:     wuqiangfu
 * @UpdateDate:     2022/7/4 19:28
 * @UpdateRemark:   说明本次修改内容
 * @Version:        v1.0
 */
public class DateUtils {

   private static final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern(DateFormatConstant.DEFAULT_DATE_TIME_FORMAT);

   private static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofPattern(DateFormatConstant.DEFAULT_DATE_FORMAT);

   private static final DateTimeFormatter SIMPLE_DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern(DateFormatConstant.SIMPLE_DATE_TIME_FORMAT);

   private static final DateTimeFormatter DEFAULT_DATE_MONTH_FORMAT = DateTimeFormatter.ofPattern(DateFormatConstant.DEFAULT_DATE_MONTH_FORMAT);

   /**
    *  获取时间格式为 yyyy-MM-dd HH:mm:ss 的字符串
    *
    * @param date 时间 LocalDateTime格式
    * @return 时间转字符串
    */
   public static String formatDateTime(LocalDateTime date) {
      return DATE_TIME_FORMATTER.format(date);
   }

   /**
    *  获取时间格式为 yyyyMMddHHmmss 的字符串
    *
    * @param date 时间 LocalDateTime格式
    * @return 时间转字符串
    */
   public static String formatSimpleDateTime(LocalDateTime date) {
      return SIMPLE_DATE_TIME_FORMATTER.format(date);
   }

   /**
    *  获取时间格式为 yyyy-MM-dd 的字符串
    *
    * @param date 时间 LocalDate格式
    * @return 时间转字符串
    */
   public static String formatDate(LocalDate date) {
      return DATE_FORMATTER.format(date);
   }

   /**
    *  获取时间格式为 yyyy-MM-dd 的字符串
    *
    * @param date 时间 LocalDateTime格式
    * @return 时间转字符串
    */
   public static String formatDate(LocalDateTime date) {
      return DATE_FORMATTER.format(date);
   }

   /**
    *  获取时间格式为 yyyy-MM 的字符串
    *
    * @param date 时间 LocalDateTime格式
    * @return 时间转字符串
    */
   public static String formatDateMonth(LocalDateTime date) {
      return DEFAULT_DATE_MONTH_FORMAT.format(date);
   }

   /**
    *  获取时间格式为 yyyy-MM-dd 的时间
    *
    * @param time yyyy-MM-dd的字符串
    * @return 返回时间
    */
   public static LocalDate parseDate(String time){ return LocalDate.parse(time, DATE_FORMATTER); }

   /**
    *  获取时间格式为 yyyy-MM-dd HH:mm:ss 的时间
    *
    * @param time yyyy-MM-dd HH:mm:ss 格式的字符串
    * @return 返回时间
    */
   public static LocalDateTime parseDateTime(String time){
      return DateUtil.parse(time).toLocalDateTime();
   }

   /**
    *  获取时间格式为 yyyy-MM-dd HH:mm:ss 的时间（入参可为空）
    *
    * @param time yyyy-MM-dd HH:mm:ss 格式的字符串
    * @return 返回时间
    */
   public static LocalDateTime parseDateTimeNullable(String time){
      if (StringUtils.isBlank(time)){
         return null;
      }
      return LocalDateTime.parse(time, DATE_TIME_FORMATTER);
   }

   /**
    *  获取时间格式为 yyyy-MM-dd HH:mm:ss 的时间
    *
    * @param time yyyyMMddHHmmss 格式的字符串
    * @return 返回时间
    */
   public static LocalDateTime parseSimpleDateTime(String time) {
      return LocalDateTime.parse(time, SIMPLE_DATE_TIME_FORMATTER);
   }

   /**
    * wuqiangfu special annotation
    *
    * java1.8之后判断
    *
    * @param nowTime 需要比较时间
    * @param startTime 开始时间
    * @param endTime 结束时间
    * @return v true-在   false-不在
    * @Description:   判断该时间是否在时间范围之内
    */
   public static boolean isEffectiveLocalDate (LocalDateTime nowTime, LocalDateTime startTime, LocalDateTime endTime) {
      return nowTime.isAfter(startTime) && nowTime.isBefore(endTime);
   }

   /**
    * wuqiangfu special annotation
    *
    * @return v
    * @Description:  获取今年
    */
   public static String getLocalYear () {
      return String.valueOf(LocalDate.now().getYear());
   }

   /**
    * wuqiangfu special annotation
    *
    * @param  time  时间
    * @return v
    * @Description:  检验时间是否在当前时间之后
    */
   public static Boolean isTimeFrom (LocalDateTime time) {
      Duration between = Duration.between(LocalDateTime.now(), time);
      return between.toMillis() <= 0;
   }

   /**
    * 按照JVM时区获取代表当前时间的紧凑格式字符串。
    *
    * @return 当前时间，格式为：yyyyMMddHHmmss
    */
   public static String getCurDateTimeCompStr() {
      return getCurTimeByFormat(DateFormatConstant.SIMPLE_DATE_TIME_FORMAT);
   }

   /**
    * 按照JVM时区获取指定格式的当前时间字符串。
    *
    * @param format 时间格式
    * @return 当前时间字符串
    */
   public static String getCurTimeByFormat(String format) {
      return DateFormatUtils.format(new Date(), format);
   }
   /**
    * 通过时间戳(秒)返回时间
    *
    * @param timestamp 时间戳
    * @return LocalDateTime
    */
   public static LocalDateTime timestampToDateTime(Long timestamp) {
      return dateToLocalDateTime(new Date(timestamp));
   }
   /**
    * Date 转化为 LocalDateTime
    *
    * @param date java.util.Date
    * @return java.time.LocalDateTime
    */
   public static LocalDateTime dateToLocalDateTime(Date date) {
      return date.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();
   }
//   /**
//    * 获取当前时间字符串
//    *
//    * @return 当前时间, 格式为: yyyy-MM-dd HH:mm:ss
//    */
//   public static String getNowDateTime() {
//      return dateTimeToStr(LocalDateTime.now(), DateFormatConstant.DEFAULT_DATE_TIME_FORMAT);
//   }
//   /**
//    * LocalDateTime 转为 字符串
//    *
//    * @param localDateTime 时间
//    * @param format        时间格式
//    * @return 日期字符串
//    */
//   public static String dateTimeToStr(LocalDateTime localDateTime, String format) {
//      if (Objects.isNull(localDateTime) || StringUtils.isBlank(format)) {
//         return StringUtils.EMPTY;
//      }
//      DateTime dateTime = new DateTime(localDateTimeToDate(localDateTime));
//      return dateTime.toString(format);
//   }
//   /**
//    * LocalDate 转为 默认格式字符串(yyyy-MM-dd HH:mm:ss)
//    *
//    * @param localDateTime 日期
//    * @return 日期字符串
//    */
//   public static String dateTimeToStr(LocalDateTime localDateTime) {
//      if (Objects.isNull(localDateTime)) {
//         return StringUtils.EMPTY;
//      }
//      DateTime dateTime = new DateTime(localDateTimeToDate(localDateTime));
//      return dateTime.toString(DateFormatConstant.DEFAULT_DATE_TIME_FORMAT);
//   }
   /**
    * LocalDateTime 转化为 Date
    *
    * @param localDateTime java.time.LocalDateTime
    * @return java.util.Date
    */
   private static Date localDateTimeToDate(LocalDateTime localDateTime) {
      return Date.from(localDateTime.atZone(ZoneId.systemDefault()).toInstant());
   }

   /**
    * 获取当天剩余秒数
    * @return
    */
   public static int remainTimeToday(){
      Calendar curDate = Calendar.getInstance();
      Calendar tomorrowDate = new GregorianCalendar(curDate.get(Calendar.YEAR), curDate.get(Calendar.MONTH), curDate.get(Calendar.DATE) + 1, 0, 0, 0);
      int second = (int)(tomorrowDate.getTimeInMillis() - curDate.getTimeInMillis()) / 1000;
      return second;
   }

   /**
    * 比较时间是否在某个时间范围内
    *
    * @param compareTime 比较时间
    * @param startTime   开始范围
    * @param endTime     结束范围
    * @return v
    */
   public static boolean between(LocalDateTime compareTime, LocalDateTime startTime, LocalDateTime endTime) {
      if (compareTime == null || startTime == null || endTime == null) {
         return false;
      }
      return compareTime.compareTo(startTime) >= 0 && compareTime.compareTo(endTime) < 1;
   }

}
